/*
 * Copyright (C) 2021 Chinasoft International
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.example.javajscommunication;

import com.example.javajscommunication.RequestParam;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.rpc.*;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.utils.zson.ZSONObject;

import java.util.HashMap;
import java.util.Map;


public class ServiceAbility extends Ability {
    // 定义日志标签
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "ServiceAbility");

    private MyRemote remote = new MyRemote();
    private int number = 0;
    RequestParam param = new RequestParam();
    MessageOption option = new MessageOption();
    Map<String, Object> zsonEvent = new HashMap<String, Object>();

    // FA在请求PA服务时会调用Ability.connectAbility连接PA，连接成功后，需要在onConnect返回一个remote对象，供FA向PA发送消息
    @Override
    protected IRemoteObject onConnect(Intent intent) {
        super.onConnect(intent);
        return remote.asObject();
    }

    class MyRemote extends RemoteObject implements IRemoteBroker {
        private static final int ACTION_MESSAGE_CODE_PLUS = 1001;//求积
        private static final int ACTION_MESSAGE_CODE_PLUS_SUB = 1002;//订阅
        private static final int ACTION_MESSAGE_CODE_PLUS_UNSUB = 1003;//取消订阅
        private static final int SUCCESS = 0;

        private boolean go = true; // 开启下载状态 true可以下载 false 停止下载


        private IRemoteObject remoteObjectHandler;

        MyRemote() {
            super("MyService_MyRemote");
        }

        @Override
        public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
            switch (code) {

                case ACTION_MESSAGE_CODE_PLUS: {
                    String zsonStr = data.readString(); // 获取传入参数的字符串
                    RequestParam param = new RequestParam();
                    try {
                        param = ZSONObject.stringToClass(zsonStr, RequestParam.class); // 字符串对象转成RequestParam实例
                    } catch (RuntimeException e) {

                    }

                    // 返回结果仅支持可序列化的Object类型
                    Map<String, Object> zsonResult = new HashMap<>();
                    zsonResult.put("code", SUCCESS);
                    zsonResult.put("abilityResult", param.getFirstNum() + " * " + param.getSecondNum() + " = " + (param.getFirstNum() * param.getSecondNum()));
                    reply.writeString(ZSONObject.toZSONString(zsonResult)); // 数据返回给js端
                    return true;
                }
                case ACTION_MESSAGE_CODE_PLUS_SUB: {
                    go = true; // 开启可以下载状态
                    remoteObjectHandler = data.readRemoteObject(); // 获取请求参数对象
                    String zsonStr = data.readString(); // 获取参数字符串

                    try {
                        param = ZSONObject.stringToClass(zsonStr, RequestParam.class); // 字符串对象转成RequestParam实例
                    } catch (RuntimeException e) {

                    }
                    startNotify(param); // 给js端发送信息

                    Map<String, Object> zsonResult = new HashMap<String, Object>();// 返回结果，关键字段应与Js方协商
                    zsonResult.put("code", SUCCESS);
                    reply.writeString(ZSONObject.toZSONString(zsonResult)); // map 对象转成json字符串，并返回给js端
                    return true;
                }
                case ACTION_MESSAGE_CODE_PLUS_UNSUB: {
                    go = false; // 停止方法startNotify中的while循环,停止往js端发送消息
                    Map<String, Object> zsonResult = new HashMap<String, Object>();
                    zsonResult.put("code", SUCCESS);
                    reply.writeString(ZSONObject.toZSONString(zsonResult));
                    return true;
                }
                default: {
                    Map<String, Object> zsonResult = new HashMap<String, Object>();
                    zsonResult.put("abilityError", "传输错误");
                    reply.writeString(ZSONObject.toZSONString(zsonResult));
                    return false;
                }
            }
        }

        /**
         * 开启线程，按照5*3 每15毫秒的频率返回数据给js端。这里java发送给js的数据，
         * js端会通过订阅java pa的回调函数中而实时获取到
         */
        public void startNotify(RequestParam param) {
            number = param.getFirstNum(); // 获取当前进度值从请求中获取
            new Thread(() -> { // 开启线程
                while (go) {
                    try {
                        Thread.sleep(5 * 3); // 线程睡眠15毫秒后继续往下执行
                        MessageParcel data = MessageParcel.obtain(); // 创建索引为0的空MessageParcel对象
                        MessageParcel reply = MessageParcel.obtain();
                        zsonEvent.put("abilityEvent", number++);
                        if (number == 101) { // number超过100 go状态设为false 下载结束
                            go = false;
                        }
                        data.writeString(ZSONObject.toZSONString(zsonEvent)); // 数据存到MessageParcel载体
                        remoteObjectHandler.sendRequest(100, data, reply, option); // 发送
                        reply.reclaim(); // 回收
                        data.reclaim();
                    } catch (RemoteException | InterruptedException e) {
                        break;
                    }
                }
            }).start();
        }

        @Override
        public IRemoteObject asObject() {
            return this;
        }
    }

}